home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xpaint-2.1.1 / blobOp.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  8KB  |  245 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. #include <X11/Intrinsic.h>
  16. #include <X11/StringDefs.h>
  17. #include <X11/cursorfont.h>
  18. #include "xpaint.h"
  19. #include "misc.h"
  20. #include "Paint.h"
  21.  
  22. #define FILL            0x2
  23. #define POLY            0x1
  24. #define IsPoly(x)       (x & POLY)
  25. #define IsFill(x)       (x & FILL)
  26.  
  27. typedef struct {
  28.     Boolean    flag;
  29.     int    startX, startY, lastX, lastY;
  30.     GC    gc1, gc2;
  31.         int     npoints, size;
  32.         XPoint  *points, *real;
  33. } LocalInfo;
  34.  
  35. static void    press(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info) 
  36. {
  37.     XRectangle    undo;
  38.  
  39.     if (info->surface == opWindow)
  40.         return;
  41.  
  42.     if ((event->state & 
  43.             (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)) != 0)
  44.         return;
  45.  
  46.     l->lastX = l->startX = event->x;
  47.     l->lastY = l->startY = event->y;
  48.      l->npoints = 0;
  49.         if (IsFill(l->flag)) {
  50.         l->points[l->npoints].x = event->x;
  51.         l->points[l->npoints].y = event->y;
  52.         l->real[l->npoints].x = info->x;
  53.         l->real[l->npoints].y = info->y;
  54.         l->npoints++;
  55.     }
  56.  
  57.     undo.x      = event->x;
  58.     undo.y      = event->y;
  59.     undo.width  = 1;
  60.     undo.height = 1;
  61.  
  62.     if (event->button == Button2)
  63.     {
  64.         l->gc1 = info->second_gc;
  65.         l->gc2 = info->first_gc;
  66.     }
  67.     else
  68.     {
  69.         l->gc1 = info->first_gc;
  70.         l->gc2 = info->second_gc;
  71.     }
  72.  
  73.     UndoStartPoint(w, info, event->x, event->y);
  74.  
  75.     XDrawLine(XtDisplay(w), info->drawable, l->gc1,
  76.              l->lastX, l->lastY, event->x, event->y);
  77.     if (!info->isFat)
  78.         XDrawLine(XtDisplay(w), XtWindow(w), l->gc1,
  79.              l->lastX, l->lastY, event->x, event->y);
  80.  
  81.     PwUpdate(w, &undo, False);
  82. }
  83.  
  84. static void    motion(Widget w, LocalInfo *l, XMotionEvent *event, OpInfo *info) 
  85. {
  86.     XRectangle    undo;
  87.  
  88.     if (info->surface == opWindow)
  89.         return;
  90.  
  91.     XDrawLine(XtDisplay(w), info->drawable,l->gc1,
  92.              l->lastX, l->lastY, event->x, event->y);
  93.     if (!info->isFat)
  94.         XDrawLine(XtDisplay(w), XtWindow(w), l->gc1,
  95.              l->lastX, l->lastY, event->x, event->y);
  96.  
  97.     UndoGrow(w, event->x, event->y);
  98.  
  99.     undo.x      = MIN(l->lastX, event->x);
  100.     undo.y      = MIN(l->lastY, event->y);
  101.     undo.width  = MAX(l->lastX, event->x) - undo.x + 1;
  102.     undo.height = MAX(l->lastY, event->y) - undo.y + 1;
  103.  
  104.     l->lastX = event->x;
  105.     l->lastY = event->y;
  106.         if (IsFill(l->flag)) {
  107.         l->points[l->npoints].x = event->x;
  108.         l->points[l->npoints].y = event->y;
  109.         l->real[l->npoints].x = info->x;
  110.                 l->real[l->npoints].y = info->y;
  111.         l->npoints++;
  112.         if (l->npoints > l->size - 3) {
  113.             l->size += 256;
  114.             l->real   = (XPoint*)XtRealloc((XtPointer)l->real,
  115.                         sizeof(XPoint) * l->size);
  116.             l->points = (XPoint*)XtRealloc((XtPointer)l->points, 
  117.                         sizeof(XPoint) * l->size);
  118.         }
  119.     }
  120.  
  121.     PwUpdate(w, &undo, False);
  122. }
  123. static void    release(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info) 
  124. {
  125.     XRectangle      undo;
  126.  
  127.         int     mask;
  128.         /*
  129.         **  Check to make sure all buttons are up, before doing this
  130.         */
  131.         mask = Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask;
  132.         switch (event->button) {
  133.         case Button1:   mask ^= Button1Mask; break;
  134.         case Button2:   mask ^= Button2Mask; break;
  135.         case Button3:   mask ^= Button3Mask; break;
  136.         case Button4:   mask ^= Button4Mask; break;
  137.         case Button5:   mask ^= Button5Mask; break;
  138.         }
  139.         if ((event->state & mask) != 0)
  140.                 return;
  141.     l->points[l->npoints].x = event->x;
  142.     l->points[l->npoints].y = event->y;
  143.     l->real[l->npoints].x = info->x;
  144.         l->real[l->npoints].y = info->y;
  145.     l->npoints++;
  146.  
  147.     UndoGrow(w, event->x, event->y);
  148.  
  149.     undo.x      = MIN(l->lastX, event->x);
  150.     undo.y      = MIN(l->lastY, event->y);
  151.     undo.width  = MAX(l->lastX, event->x) - undo.x + 1;
  152.     undo.height = MAX(l->lastY, event->y) - undo.y + 1;
  153.  
  154.     if (IsFill(l->flag)) {
  155.                 if (!info->isFat)
  156.                         XFillPolygon(XtDisplay(w), XtWindow(w), l->gc2,
  157.                                 l->real, l->npoints, Complex, CoordModeOrigin);
  158.                 XFillPolygon(XtDisplay(w),  info->drawable, l->gc2,
  159.                                 l->real, l->npoints, Complex,CoordModeOrigin);
  160.                 l->points[l->npoints].x = l->points[0].x;
  161.                 l->points[l->npoints].y = l->points[0].y;
  162.                 l->real[l->npoints].x = l->real[0].x;
  163.                 l->real[l->npoints].y = l->real[0].y;
  164.                 l->npoints++;
  165.             if (!info->isFat)
  166.                     XDrawLines(XtDisplay(w), XtWindow(w), l->gc1,
  167.                             l->real, l->npoints, CoordModeOrigin);
  168.             XDrawLines(XtDisplay(w),  info->drawable, l->gc1,
  169.                         l->real, l->npoints, CoordModeOrigin);
  170.         }
  171.     else
  172.     {
  173.         l->lastX = event->x;
  174.         l->lastY = event->y;
  175.             XDrawLine(XtDisplay(w), info->drawable,l->gc1,
  176.                          l->lastX, l->lastY, l->startX, l->startY);
  177.             if (!info->isFat)
  178.                     XDrawLine(XtDisplay(w), XtWindow(w), l->gc1,
  179.                              l->lastX, l->lastY, l->startX, l->startY);
  180.  
  181.     }
  182.  
  183.         PwUpdate(w, NULL, False);
  184. }
  185.  
  186. /*
  187. **  Those public functions
  188. */
  189. void *FreehandAdd(Widget w)
  190. {
  191.     LocalInfo    *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  192.  
  193.     XtVaSetValues(w, XtNcompress, False, NULL);
  194.     l->flag = 0;
  195.  
  196.     l->size   = 256;
  197.     l->real   = (XPoint*)XtCalloc(sizeof(XPoint), l->size);
  198.     l->points = (XPoint*)XtCalloc(sizeof(XPoint), l->size);
  199.  
  200.     OpAddEventHandler(w, opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
  201.     OpAddEventHandler(w, opPixmap, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  202.     OpAddEventHandler(w, opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  203.     SetPencilCursor(w);
  204.  
  205.     return l;
  206. }
  207. void FreehandRemove(Widget w, LocalInfo *l)
  208. {
  209.     OpRemoveEventHandler(w, opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
  210.     OpRemoveEventHandler(w, opPixmap, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  211.     OpRemoveEventHandler(w, opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  212.  
  213.     XtFree((XtPointer)l->real);
  214.     XtFree((XtPointer)l->points);
  215.     XtFree((XtPointer)l);
  216. }
  217. void *FFreehandAdd(Widget w)
  218. {
  219.     LocalInfo    *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  220.     l->flag = FILL;
  221.  
  222.     l->size   = 256;
  223.     l->real   = (XPoint*)XtCalloc(sizeof(XPoint), l->size);
  224.     l->points = (XPoint*)XtCalloc(sizeof(XPoint), l->size);
  225.  
  226.     XtVaSetValues(w, XtNcompress, True, NULL);
  227.  
  228.     OpAddEventHandler(w, opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
  229.     OpAddEventHandler(w, opPixmap, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  230.     OpAddEventHandler(w, opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  231.  
  232.     SetPencilCursor(w);
  233.  
  234.     return l;
  235. }
  236. void FFreehandRemove(Widget w, LocalInfo *l)
  237. {
  238.     OpRemoveEventHandler(w, opPixmap, ButtonPressMask, FALSE, (OpEventProc)press, l);
  239.     OpRemoveEventHandler(w, opPixmap, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  240.     OpRemoveEventHandler(w, opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  241.     XtFree((XtPointer)l->real);
  242.     XtFree((XtPointer)l->points);
  243.     XtFree((XtPointer)l);
  244. }
  245.